package com.example.rtmppusher.push;

import android.app.Activity;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;

import com.example.rtmppusher.util.CameraUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


public class CameraPreviewHandler {

    Activity activity;

    boolean previewing = false;

    //相机对象
    Camera camera;

    public int getFace() {
        return face;
    }

    public int getCameraOrientation() {
        return cameraOrientation;
    }

    public int getDisplayRotation() {
        return displayRotation;
    }

    int face = Camera.CameraInfo.CAMERA_FACING_BACK;

    //摄像头预览时使用的画面尺寸
    Camera.Size previewSize;

    public Camera.Size getPreviewSize() {
        return previewSize;
    }

    //推流监听器
    EventListener listener;

    //摄像头方向
    int cameraOrientation;

    //屏幕旋转角度
    int displayRotation;

    //预览时采集数据的旋转角度
    int previewRotation;

    //摄像头帧预览数据回调
    //data是原始采集的数据，经过旋转得到预览数据，存入bytes里面
    final Camera.PreviewCallback cameraPreviewCallback = (data, camera) -> {
        if (data != null)
            listener.onVideoFrame(data);
    };

    public CameraPreviewHandler(Activity activity, EventListener eventListener) {
        this.activity = activity;
        this.listener = eventListener;
    }

    //切换摄像头
    public void switchCamera() {
        synchronized (this) {
            face = face == Camera.CameraInfo.CAMERA_FACING_BACK ?
                    Camera.CameraInfo.CAMERA_FACING_FRONT :
                    Camera.CameraInfo.CAMERA_FACING_BACK;
            listener.onCameraSwitch(face);
        }
    }

    //开始预览
    public void startPreview() {
        synchronized (this) {
            //打开摄像头
            camera = Camera.open(face);
            //设置预览图像的格式
            Camera.Parameters parameters = camera.getParameters();
            if (face == Camera.CameraInfo.CAMERA_FACING_BACK) {
                parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
            }
            parameters.setPreviewFormat(ImageFormat.NV21);
            setPreviewSize(parameters);
            camera.setParameters(parameters);
            //通知回调对象，画面参数改变
            listener.onVideoParamChange(previewSize.width, previewSize.height);
            //开始预览
            camera.setPreviewCallback(cameraPreviewCallback);
            camera.startPreview();
            //更新预览方向
            setPreviewOrientation();
            previewing = true;
        }
    }

    //停止预览
    public void stopPreview() {
        synchronized (this) {
            if (camera == null) return;
            camera.setPreviewCallback(null);
            camera.stopPreview();
            camera.release();
            camera = null;
            previewing = false;
        }
    }

    //设置摄像头预览方向
    //安卓手机中，摄像头采集画面的方向，和我们手持的方向是不一致的
    //一般安卓手机都是以手机右侧作为画面的上方，手机上侧作为画面的左方，这个方向是固定的，即使屏幕旋转，摄像头的采集方向也不会变化
    //如果我们直接以摄像头采集到的像素作为预览画面，看到的可能会是横竖倒置或上下颠倒的图像
    //所以我们必须根据摄像头的采集方向，和屏幕旋转的方向，来计算预览时，要将采集像素旋转一定角度后再显示，一般是0，90，180，270四个值
    public void setPreviewOrientation() {
        cameraOrientation = CameraUtils.getCameraOrientation(face);
        displayRotation = CameraUtils.getDisplayRotation(activity);
        previewRotation = CameraUtils.getPreviewRotation(face, cameraOrientation, displayRotation);
        camera.setDisplayOrientation(previewRotation);
    }

    //设置摄像头预览尺寸
    //尺寸选取规则是，在176 * 144-1920 * 1080清晰度之间，选择比例和预设比例最为接近的
    protected void setPreviewSize(Camera.Parameters parameters) {
        int[] displaySize = CameraUtils.getDisplaySize(activity);
        for (int i = 0; i < displaySize.length; i++) {
            Log.e("Camera", "i = " + displaySize[i]);
        }
        double preferedRatio = (double) displaySize[0] / (double) displaySize[1];
        Log.e("Camera", "preferRatio:" + preferedRatio);
        List<Camera.Size> bestSizes = new ArrayList<>();
        List<Camera.Size> sizeList = parameters.getSupportedPreviewSizes();
        for (Camera.Size size : sizeList) {
//            Log.e("Camera", "width: " + size.width + ",height: " + size.height);
            if (size.width * size.height >= 176 * 144 && size.width * size.height <= 1280 * 720) {
                double ratio = Math.abs((double) size.width / (double) size.height);
                double dRatio = Math.abs(ratio - preferedRatio);
//                Log.e("Camera", String.valueOf(ratio));
                if (dRatio < 0.1) {
                    bestSizes.add(size);
//                    break;
                }
//                if (dRatio == bestRatio && size.width * size.height > bestSize.width * bestSize.height)
//                    bestSize = size;
            }
        }
        for (Camera.Size bestSize : bestSizes) {
            Log.e("Camera", "width: " + bestSize.width + ", height: " + bestSize.height + ",ratio: " + (bestSize.width * 1.0 / bestSize.height));
        }
        if (bestSizes.size() == 0)
            previewSize = sizeList.get(0);
        else {
            previewSize = bestSizes.get(0);
        }
        Log.e("Camera", "width: " + previewSize.width + ", height: " + previewSize.height);
        parameters.setPreviewSize(previewSize.width, previewSize.height);
    }

    //设置用于显示视频的SurfaceHolder
    public void setPreviewDisplay(SurfaceHolder surfaceHolder) {
        if (camera != null) {
            try {
                camera.setPreviewDisplay(surfaceHolder);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

